package proto

import (
	"errors"
	"os"
	"path/filepath"
	"strings"

	"github.com/emicklei/proto"
)

type Target struct {
	ServiceName string
	NoteName    string
}

// 解析所有proto文件内容
func ParseProtos(protoFile string) ([]*Target, error) {
	protos, err := getProtoFiles(protoFile)
	if err != nil {
		return nil, err
	}
	if len(protos) <= 0 {
		errors.New("no proto file")
	}
	srvs := make([]*Target, 0)
	for _, p := range protos {
		if err := parseProto(p, &srvs); err != nil {
			return nil, err
		}
	}

	return srvs, nil
}

// 解析proto文件内容
func parseProto(file string, srvs *[]*Target) error {
	reader, err := os.Open(file)
	if err != nil {
		return err
	}
	defer reader.Close()

	p := proto.NewParser(reader)
	d, err := p.Parse()
	if err != nil {
		return err
	}

	for _, e := range d.Elements {
		switch v := e.(type) {
		case *proto.Service: // 解析service
			*srvs = append(*srvs, parseService(v))
		}
	}
	return nil
}

// 解析service
func parseService(ps *proto.Service) *Target {
	cPathLine := "未知分组"
	if ps.Comment != nil && len(ps.Comment.Lines) > 0 {
		cPathLine = ps.Comment.Lines[0]
	}

	return &Target{
		ServiceName: ps.Name,
		NoteName:    strings.TrimSpace(cPathLine),
	}
}

// 获取目录下所有proto文件名称
func getProtoFiles(protoFile string) ([]string, error) {
	files, err := filepath.Glob(protoFile + "/*.proto")
	if err != nil {
		return nil, err
	}

	return files, nil
}
